package com.hbmcc.deviceinfo.utils

import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.content.res.Configuration
import android.net.ConnectivityManager
import android.net.wifi.WifiManager
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager.*
import android.text.TextUtils
import android.util.TypedValue
import androidx.core.content.ContextCompat
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.SocketException
import java.util.*
import kotlin.math.roundToInt


/**
 * Copyright (c)2017
 * 欣网互联网络科技有限公司
 * author: lpc
 * created on: 2018/3/13 0013
 * description: 设备工具
 */
object DeviceUtil {
    /**
     * dp转换px
     */
    @JvmStatic
    fun dp2px(dpValue: Float, context: Context?): Int {
        if (context == null) return (dpValue * 2).toInt()
        val px = TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, dpValue,
            context.resources.displayMetrics
        )
        return px.roundToInt()
    }


    @JvmStatic
    fun intDeviceType(context: Context?): String {
        if (context == null) return "未知"
        return if ((context.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK) < Configuration.SCREENLAYOUT_SIZE_LARGE)
            "手机"
        else if (context.packageManager.hasSystemFeature("android.hardware.type.television")) "电视" else "平板"
    }

    /**
     * 无论是否有 Manifest.permission.READ_PHONE_STATE 小米 Android 11都获取不到
     * 如果编译环境(compileSdkVersion)大于等于 29 都会报异常 java.lang.SecurityException: getSubscriberId
     * 所以Android 10版本不能获取这个字段
     * 现在Android10 是真的获取不到IMEI标识了！现在移动安全联盟出的那个架包 目前只支持国内手机，三星手机不支持，而且 国内手机也不一定全部支持
     */
    @SuppressLint("HardwareIds")
    fun getImsi(context: Context?): String? {
        try {
            if (context == null) return null
            val mTelephonyMgr =
                context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            return if (ContextCompat.checkSelfPermission(
                    context,
                    Manifest.permission.READ_PHONE_STATE
                ) == PackageManager.PERMISSION_GRANTED
            ) {
                mTelephonyMgr.subscriberId
            } else null
        } catch (e: Exception) {
            return null
        }

    }


    fun getIPAddress(context: Context?): String? {
        if (context == null) return null
        val info =
            (context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
        if (info != null && info.isConnected) {
            if (info.type == ConnectivityManager.TYPE_MOBILE) { //当前使用2G/3G/4G网络
                try {
                    //Enumeration<NetworkInterface> en=NetworkInterface.getNetworkInterfaces();
                    val en: Enumeration<NetworkInterface> = NetworkInterface.getNetworkInterfaces()
                    while (en.hasMoreElements()) {
                        val intf: NetworkInterface = en.nextElement()
                        val enumIpAddr: Enumeration<InetAddress> = intf.getInetAddresses()
                        while (enumIpAddr.hasMoreElements()) {
                            val inetAddress: InetAddress = enumIpAddr.nextElement()
                            if (!inetAddress.isLoopbackAddress() && inetAddress is Inet4Address) {
                                return inetAddress.getHostAddress()
                            }
                        }
                    }
                } catch (e: SocketException) {
                    e.printStackTrace()
                }
            } else if (info.type == ConnectivityManager.TYPE_WIFI) { //当前使用无线网络
                val wifiManager =
                    context.getSystemService(Context.WIFI_SERVICE) as WifiManager
                val wifiInfo = wifiManager.connectionInfo
                //调用方法将int转换为地址字符串
                return intIP2StringIP(wifiInfo.ipAddress) //得到IPV4地址
            }
        }
        return null
    }

    private fun intIP2StringIP(ip: Int): String {
        return (ip and 0xFF).toString() + "." +
                (ip shr 8 and 0xFF) + "." +
                (ip shr 16 and 0xFF) + "." +
                (ip shr 24 and 0xFF)
    }

    /**
     * 获取网络运营商名称
     * <p>中国移动、如中国联通、中国电信</p>
     *
     * @return 运营商名称
     */
    @JvmStatic
    fun getNetworkOperatorName(context: Context?): String {
        // No sim
        if (!hasSim(context)) return "未知"

        val tm = context!!.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
        val operator = tm?.getSimOperator();
        if ("46001" == operator || "46006" == operator || "46009" == operator) {
            return "中国联通";
        } else if ("46000" == operator || "46002" == operator || "46004" == operator || "46007" == operator) {
            return "中国移动";

        } else if ("46003" == operator || "46005" == operator || "46011" == operator) {
            return "中国电信";
        } else {
            return "未知";
        }

        return "未知";
    }


    @JvmStatic
    fun getNetworkType(context: Context?): String {
        if (context == null) return "未知"
        val networkInfo = (context
            .getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager).activeNetworkInfo
        if (networkInfo == null || !networkInfo.isConnected) return "未知"
        if (networkInfo.type == ConnectivityManager.TYPE_WIFI) return "WiFi"
        if (networkInfo.type != ConnectivityManager.TYPE_MOBILE) return "未知"
        return getNetworkClass(networkInfo.type)
        /*return when (networkInfo.subtype) {
            TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_IDEN -> "2G"
            TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_HSPA, TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyManager.NETWORK_TYPE_HSPAP -> "3G"
            TelephonyManager.NETWORK_TYPE_LTE -> "4G"
            else ->
                if (networkInfo.subtypeName.equals(
                        "TD-SCDMA",
                        ignoreCase = true
                    ) || networkInfo.subtypeName.equals(
                        "WCDMA",
                        ignoreCase = true
                    ) || networkInfo.subtypeName.equals("CDMA2000", ignoreCase = true)
                ) {
                    "3G"
                } else {
                    networkInfo.subtypeName
                }
        }*/
    }

    fun getNetworkClass(networkType: Int): String {
        return when (networkType) {
            NETWORK_TYPE_GPRS, NETWORK_TYPE_EDGE, NETWORK_TYPE_CDMA, NETWORK_TYPE_1xRTT, NETWORK_TYPE_IDEN -> "2G"
            NETWORK_TYPE_UMTS, NETWORK_TYPE_EVDO_0, NETWORK_TYPE_EVDO_A, NETWORK_TYPE_HSDPA, NETWORK_TYPE_HSUPA, NETWORK_TYPE_HSPA, NETWORK_TYPE_EVDO_B, NETWORK_TYPE_EHRPD, NETWORK_TYPE_HSPAP -> "3G"
            NETWORK_TYPE_LTE -> "4G"
            else -> "未知"
        }
    }

    /**
     * 检查手机是否有sim卡
     */
    @JvmStatic
    private fun hasSim(context: Context?): Boolean {
        val tm = context?.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
        return !TextUtils.isEmpty(tm?.simOperator)
    }

    /**
     * 判断数据流量开关是否打开
     *
     * @param context
     * @return
     */
    @SuppressLint("DiscouragedPrivateApi")
    public fun isMobileDataEnabled(context: Context?): Boolean {
        if (context == null) return false
        try {
            val method = ConnectivityManager::class.java.getDeclaredMethod("getMobileDataEnabled");
            method.isAccessible = true;
            val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE);
            return method.invoke(connectivityManager) as Boolean
        } catch (t: Throwable) {
            return false;
        }
    }

}